import com.troyworks.tester.BaseTester;
import com.troyworks.hsmf.Hsmf;
import com.troyworks.util.DesignByContractError;
import com.troyworks.util.DesignByContract;
import com.troyworks.tester.ATest;
import com.troyworks.tester.ITestRunner;
import com.troyworks.hsmf.TwoStateToggle;

/**
 * @author Troy Gardner
 */
class com.troyworks.hsmf.TestHsmf {
	public var REQUIRE : Function;
	public var ASSERT : Function;

	public var tests : Array = new Array();
	public var testsFinished:Number = 0;
	
	/*************************************************************
	 * TestHsmf
	 */
	public function TestHsmf(initState : Function, name : String) {
		DesignByContract.initialize(this);	
	}
	public static function main(container_mc : MovieClip) : Void {
		trace("main---------------------------------");
		var thf : TestHsmf = new TestHsmf();
		thf.loadTests();
		thf.runTests();
		//thf.gradeTests();
	}
	public function loadTests() : Void{
	//	addSimpleTest(testEmptyConstructor, "testEmptyConstructor", "hsm requires a name to work, (necessary for debugging practically, when tons are floating around)");
	//	addSimpleTest(testNullStateConstructor, "testNullStateConstructor", "hsm requires a name to work, (necessary for debugging practically, when tons are floating around)");
	//	addSimpleTest(testToggleConstructor, "testToggleConstructor");
		addSimpleTest(testToggleInitState, "testToggleInitState");
	}
	public function addSimpleTest(test:Function, name:String, failedDescription:String):Void{
		addTest(new ATest(test, name, failedDescription));
	}
	public function addTest(test:ATest):Void{
		test.addEventListener(ATest.EVTD_TESTFINISHED, this, this.onChildTestCompleted);
		tests.push(test);
	}
	public function runTests() : Void{
		trace("running Tests\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\");
		for (var i : Number = 0; i < tests.length; i++) {
			var ct : ATest = ATest(tests[i]);
			trace("starting test " + i + " " + ct.description+ "----------------------------------------------------------------");
			ct.startTest();
		}	
	}
	public function onChildTestCompleted():Void{
		testsFinished++;
		trace("TestHsmf.onChildTestCompleted"  + testsFinished + " " +tests.length);
		
		if(testsFinished == tests.length){
			trace("finished running Tests/////////////////////////////////////");
			
			gradeTests();
		}
	}
	public function gradeTests() : Void{
		trace("-------------Summary1 ----------------------------");
		for (var i : Number = 0; i < tests.length; i++) {

			var ct : ATest = ATest(tests[i]);
			trace("  " + i + " " +ct);
		}
		trace("-------------Summary2 ----------------------------");
		
	}

	//////////////////////// BEGIN UNIT TESTS ////////////////////////
	
	public function testToggleConstructor() : Boolean{
		var res : Boolean = false;
		try{
			trace("creating");
			var t : TwoStateToggle = new TwoStateToggle();
			res = true;	 
		}catch( e : Error){
			trace("caught error");
			res = false;
		}
		return res;
	}
	public function testToggleInitState() : Boolean{
		var res : Boolean = false;
		var t : TwoStateToggle = new TwoStateToggle();
		var tr:String = t.history.join(",");
		var desired:String = "s_initial-INIT,s_OFF-ENTRY";
		trace("HIGHLIGHT " + tr + " " + desired);
		res = tr == desired;
		return res;
	}
	
	public function testEmptyConstructor() : Boolean{
		var res : Boolean = false;
		try{
			trace("creating");
			var t : Hsmf = new Hsmf();	 
		}catch( e : Error){
			trace("caught error");
			res = true;
		}
		return res;
	}
	public function testNullStateConstructor() : Boolean{
		var res : Boolean = false;
		try{
			var t : Hsmf = new Hsmf(null, "myTestHSM" );
		 
		}catch( e : Error){
			res = true;
		}
		return res;
	}
}